package com.cmc.cloud.cmclink.doc.service.impl.special;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cmc.cloud.cmclink.doc.api.document.emums.CntrTypeEnum;
import com.cmc.cloud.cmclink.doc.api.document.emums.SpecialEnum;
import com.cmc.cloud.cmclink.doc.constants.CommonConstants;
import com.cmc.cloud.cmclink.doc.constants.SepcialCargoConstans;
import com.cmc.cloud.cmclink.doc.constants.errorconstant.SpecialCargoApplyErrorCodeConstants;
import com.cmc.cloud.cmclink.doc.constants.errorconstant.SpecialCargoOogErrorCodeConstants;
import com.cmc.cloud.cmclink.doc.entity.*;
import com.cmc.cloud.cmclink.doc.mapper.ContainerMaxPayloadMapper;
import com.cmc.cloud.cmclink.doc.mapper.SpecialCargoOogMapper;
import com.cmc.cloud.cmclink.doc.mapper.SuperWhitelistOogMapper;
import com.cmc.cloud.cmclink.doc.service.special.SpecialCargoValidateService;
import com.cmes.framework.common.exception.util.ServiceExceptionUtil;
import com.cmes.framework.ex.Assertion;
import com.cmes.framework.mybatis.core.query.LambdaQueryWrapperX;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static com.cmc.cloud.cmclink.doc.constants.errorconstant.SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_NET_WGT_ERROR;

/**
 * OogAk类型货物校验器
 *
 * @author: 申天青
 * @date: 2025/8/4
 */
@Service
public class OogAkCargoValidateServiceImpl implements SpecialCargoValidateService {
    @Resource
    private SuperWhitelistOogMapper superWhitelistOogMapper;
    @Resource
    private SpecialCargoOogMapper specialCargoOogMapper;
    @Resource
    private ContainerMaxPayloadMapper containerMaxPayloadMapper;

    private static final String CONTAINER_20FR_COMBINATION = "20FR";
    private static final String CONTAINER_40FR_COMBINATION = "40FR";
    private static final int DEFAULT_INT_VALUE = 0;

    @Override
    public void validate(Long applyId, SpecialCargoApplyDO applyDO, List<SpecialCargoCntrDO> cntrDOList, List<SpecialCargoVoyageDO> specialCargoVoyageDos) {
        Integer superHeight = DEFAULT_INT_VALUE;
        Integer superLength = DEFAULT_INT_VALUE;
        Integer superWidth = DEFAULT_INT_VALUE;
        if (StringUtils.isNotEmpty(applyDO.getPraNo())) {
            List<String> pols = specialCargoVoyageDos.stream().map(SpecialCargoVoyageDO::getPolCode).collect(Collectors.toList());
            List<String> pods = specialCargoVoyageDos.stream().map(SpecialCargoVoyageDO::getPodCode).collect(Collectors.toList());
            String porCode = applyDO.getPorCode();
            String delCode = applyDO.getDelCode();
            LambdaQueryWrapperX<SuperWhitelistOogDO> queryWrapperX = new LambdaQueryWrapperX<SuperWhitelistOogDO>()
                    .eqIfPresent(SuperWhitelistOogDO::getSpecialCargoType, SpecialEnum.AK.getValue())
                    .eqIfPresent(SuperWhitelistOogDO::getPraNo, applyDO.getPraNo())
                    .likeIfPresent(SuperWhitelistOogDO::getPors, porCode)
                    .likeIfPresent(SuperWhitelistOogDO::getDels, delCode);
            SuperWhitelistOogDO superWhitelistOogDO = superWhitelistOogMapper.selectOne(queryWrapperX);
            if (null != superWhitelistOogDO) {
                List<String> praPols = Arrays.asList(superWhitelistOogDO.getPols().split(","));
                List<String> praPods = Arrays.asList(superWhitelistOogDO.getPods().split(","));
                boolean containPol = pols.stream().anyMatch(praPols::contains);
                boolean containPod = pods.stream().anyMatch(praPods::contains);
                if (containPol && containPod) {
                    superHeight = superWhitelistOogDO.getOverallHeight();
                    superLength = superWhitelistOogDO.getOverallLength();
                    superWidth = superWhitelistOogDO.getOverallWidth();
                }
            }
        }
        for (SpecialCargoCntrDO cntr : cntrDOList) {
            //禅道：11525 需求：AK/OOG:箱型为20HC、45HC时，只需要填写 箱型、尺寸、数量、箱货总重、货物总重 、特殊堆存要求、其他都不需要填写（不用展示字段）
            String cntrSize = cntr.getCntrSize();
            String cntrType = cntr.getCntrType();
            //Net WGT	必填项，加注说明：（填写每一个框架箱装载货物净重=货物本身重量+包装重量）
            BigDecimal netWgt = cntr.getNetWgt();
            BigDecimal grossWgt = cntr.getGrossWgt();
            if (null == netWgt || netWgt.compareTo(BigDecimal.ZERO) <= 0 || null == grossWgt || grossWgt.compareTo(BigDecimal.ZERO) <= 0) {
                throw ServiceExceptionUtil.exception(SPECIAL_CARGO_OOG_NET_WGT_ERROR);
            }
            if (CommonConstants.CONTAINER_20HC.equals(cntrSize + cntrType) || CommonConstants.CONTAINER_45HC.equals(cntrSize + cntrType)) {
                continue;
            }

            SpecialCargoOogDO oogDo = specialCargoOogMapper.selectOne(new LambdaQueryWrapper<SpecialCargoOogDO>().eq(SpecialCargoOogDO::getCntrId, cntr.getId()));
            if (null == oogDo) {
                throw ServiceExceptionUtil.exception(SpecialCargoApplyErrorCodeConstants.SPECIAL_NO_OOG_ERROR);
            }
            if (CntrTypeEnum.HC.getValue().equals(cntrType)) {
                if (oogDo.getOverForward() + oogDo.getOverAfter() + oogDo.getOverLeft() + oogDo.getOverRight() + oogDo.getOverHeight() > 0) {
                    throw ServiceExceptionUtil.exception(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_HC_ERROR);
                }
            }
            if(CntrTypeEnum.OT.getValue().equals(cntrType)){
                if (oogDo.getOverForward() + oogDo.getOverAfter() + oogDo.getOverLeft() + oogDo.getOverRight() > 0) {
                    throw ServiceExceptionUtil.exception(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OT_ERROR);
                }
            }
            Integer overallLength = oogDo.getOverallLength();
            Integer overallWidth = oogDo.getOverallWidth();
            Integer overallHeight = oogDo.getOverallHeight();
            if (0 == overallLength || 0 == overallWidth || 0 == overallHeight) {
                throw ServiceExceptionUtil.exception(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_ALL_ARGUMENT_ERROR);
            }
            if (StringUtils.isNotEmpty(applyDO.getPraNo())) {
                if (0 != superLength && overallLength > superLength) {
                    throw ServiceExceptionUtil.exception(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_ALL_LENGTH);
                }
                if (0 != superWidth && overallWidth > superWidth) {
                    throw ServiceExceptionUtil.exception(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_ALL_WIDTH);
                }
                if (0 != superHeight && overallHeight > superHeight) {
                    throw ServiceExceptionUtil.exception(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_ALL_HEIGHT);
                }
            }
            LambdaQueryWrapperX<ContainerMaxPayloadDO> queryWrapperX = new LambdaQueryWrapperX<>();
            queryWrapperX.eqIfPresent(ContainerMaxPayloadDO::getCntrType, cntr.getCntrType())
                    .eqIfPresent(ContainerMaxPayloadDO::getCntrSize, cntr.getCntrSize());
            ContainerMaxPayloadDO payloadDO = containerMaxPayloadMapper.selectOne(queryWrapperX);

            int length = DEFAULT_INT_VALUE;
            int width = DEFAULT_INT_VALUE;
            int height = DEFAULT_INT_VALUE;
            int overForward = DEFAULT_INT_VALUE;
            int overAfter = DEFAULT_INT_VALUE;
            int overLeft = DEFAULT_INT_VALUE;
            int overRight = DEFAULT_INT_VALUE;
            int overHeight = DEFAULT_INT_VALUE;
            if (null != payloadDO) {
                length = payloadDO.getLength() == null ? DEFAULT_INT_VALUE : payloadDO.getLength();
                width = payloadDO.getWidth() == null ? DEFAULT_INT_VALUE : payloadDO.getWidth();
                height = payloadDO.getHeight() == null ? DEFAULT_INT_VALUE : payloadDO.getHeight();
                overForward = payloadDO.getOverForward() == null ? DEFAULT_INT_VALUE : payloadDO.getOverForward();
                overAfter = payloadDO.getOverAfter() == null ? DEFAULT_INT_VALUE : payloadDO.getOverAfter();
                overLeft = payloadDO.getOverLeft() == null ? DEFAULT_INT_VALUE : payloadDO.getOverLeft();
                overRight = payloadDO.getOverRight() == null ? DEFAULT_INT_VALUE : payloadDO.getOverRight();
                overHeight = payloadDO.getOverHeight() == null ? DEFAULT_INT_VALUE : payloadDO.getOverHeight();
            }
            if (overForward > DEFAULT_INT_VALUE && (oogDo.getOverForward() > overForward)) {
                Assertion.assertTrue(false).raise0(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_FORWARD.getCode(), cntrSize + cntrType);
            }
            if (overAfter > DEFAULT_INT_VALUE && (oogDo.getOverAfter() > overAfter)) {
                Assertion.assertTrue(false).raise0(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_AFTER.getCode(), cntrSize + cntrType);
            }
            if (overLeft > DEFAULT_INT_VALUE && (oogDo.getOverLeft() > overLeft)) {
                Assertion.assertTrue(false).raise0(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_LEFT.getCode(), cntrSize + cntrType);
            }
            if (overRight > DEFAULT_INT_VALUE && (oogDo.getOverRight() > overRight)) {
                Assertion.assertTrue(false).raise0(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_RIGHT.getCode(), cntrSize + cntrType);
            }
            if (overHeight > DEFAULT_INT_VALUE && (oogDo.getOverHeight() > overHeight)) {
                Assertion.assertTrue(false).raise0(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_OVER_HEIGHT.getCode(), cntrSize + cntrType);
            }
            if (length > DEFAULT_INT_VALUE && (overallLength + oogDo.getOverForward() + oogDo.getOverAfter() > length)) {
                throw ServiceExceptionUtil.exception(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_ALL_LENGTH);
            }
            if (width > DEFAULT_INT_VALUE && (overallWidth + oogDo.getOverLeft() + oogDo.getOverRight() > width)) {
                throw ServiceExceptionUtil.exception(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_ALL_WIDTH);
            }
            if (height > DEFAULT_INT_VALUE && (overallHeight + oogDo.getOverHeight() > height)) {
                throw ServiceExceptionUtil.exception(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_ALL_HEIGHT);
            }

            /*
             * 1、针对20FR，GROSS WEIGHT不得超过34000KG；
             * 2、针对40FR ,GROSS WEIGHT不得超过45000KG；
             * 3、当选择BB CARGO的时候，重量不受限
             */
            if (StringUtils.isEmpty(oogDo.getCornerPostStatus())) {
                if (CONTAINER_20FR_COMBINATION.equals(cntrSize + cntrType) && overallLength > SepcialCargoConstans.DEFAULT_20FR_FOR_CONER_LENGTH) {
                    throw ServiceExceptionUtil.exception(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_20FR_CONER_ARGUMENT_ERROR);
                }
                if (CONTAINER_40FR_COMBINATION.equals(cntrSize + cntrType) && overallLength > SepcialCargoConstans.DEFAULT_40FR_FOR_CONER_LENGTH) {
                    throw ServiceExceptionUtil.exception(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_40FR_CONER_ARGUMENT_ERROR);
                }
            }
            if (!oogDo.getBreakbulkCargo()) {
                if (CONTAINER_20FR_COMBINATION.equals(cntrSize + cntrType)) {
                    if (overallLength > SepcialCargoConstans.DEFAULT_20FR_LENGTH) {
                        throw ServiceExceptionUtil.exception(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_20FR_LENGTH);
                    }
                    if (overallWidth > SepcialCargoConstans.DEFAULT_20FR_WIDTH) {
                        throw ServiceExceptionUtil.exception(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_20FR_WIDTH);
                    }
                    if (overallHeight > SepcialCargoConstans.DEFAULT_20FR_HEIGHT) {
                        throw ServiceExceptionUtil.exception(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_20FR_HEIGHT);
                    }
                    if (grossWgt.compareTo(SepcialCargoConstans.DEFAULT_20FR_GROSS_WGT) > DEFAULT_INT_VALUE) {
                        throw ServiceExceptionUtil.exception(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_20FR_GROSS_WGT);
                    }
                }
                if (CONTAINER_40FR_COMBINATION.equals(cntrSize + cntrType)) {
                    if (overallLength > SepcialCargoConstans.DEFAULT_40FR_LENGTH) {
                        throw ServiceExceptionUtil.exception(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_40FR_LENGTH);
                    }
                    if (overallWidth > SepcialCargoConstans.DEFAULT_40FR_WIDTH) {
                        throw ServiceExceptionUtil.exception(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_40FR_WIDTH);
                    }
                    if (overallHeight > SepcialCargoConstans.DEFAULT_40FR_HEIGHT) {
                        throw ServiceExceptionUtil.exception(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_40FR_HEIGHT);
                    }
                    if (grossWgt.compareTo(SepcialCargoConstans.DEFAULT_40FR_GROSS_WGT) > DEFAULT_INT_VALUE) {
                        throw ServiceExceptionUtil.exception(SpecialCargoOogErrorCodeConstants.SPECIAL_CARGO_OOG_OVER_40FR_GROSS_WGT);
                    }
                }
            }
        }
    }

}
